"use strict";

String.prototype.trim = function(){return this.replace(/(^\s+)|(\s+$)/g,'');}

String.prototype.repeat = function( num ){return new Array( isNaN(num)? 1 : ++num ).join(this);}

if (!Array.prototype.forEach){
    Array.prototype.forEach = function(fun /*, thisp*/){
        var len = this.length;
        if (typeof fun != "function")
            throw new TypeError();
        var thisp = arguments[1];
        for (var i = 0; i < len; i++){
            if (i in this)
                fun.call(thisp, this[i], i, this);
        }
    };
}

//================ 全局变量 ============================

var QUESTION_SRC_UNDERLINE = ' ';
var QUESTION_SRC_UNDERLINE_MIN_LENGTH = 5;
var QUESTION_DB_UNDERLINE = '_';
var QUESTION_DB_UNDERLINE_LENGTH = 9;

//================ 页面加载完毕  =========================

$(document).ready(function(){
	$('#analysis').click(function(){
		var content = $('#content').val();
		var questions = $('#questions').val();

		analysisContent(content, function(err, htmlContent){
			if(err){
				$.dialog({
					icon:'error',
					content:err.message,
					ok: true
				});
				return;
			}
			analysisQuestions(questions, function(err, htmlQuestions){
				if(err){
					$.dialog({
						icon:'error',
						content:err.message,
						ok: true
					});
					return;
				}
				var previewHtml = htmlContent+'<br/>'+htmlQuestions;
				$('#preview').html(previewHtml);
//				$.dialog();
			});
		});
	});
});

//================ 自定义类  ==============================

var QuestionType = {
	Choice: '0', //选择题
	Cloze: '1'   //填空题
}

var Question = function(){
	this.number 	= '';
	this.type 		= QuestionType.Cloze;
	this.content 	= '';
	this.remark		= '';
	this.optionItems= [];
}

var QuestionOptionItem = function(){
	this.code 		= '';
	this.content 	= '';
	this.remark		= '';
}

//================ 自定义函数 ==============================

/**
 * @param {String} text
 * @param {Function} callback(err, htmlContent)
 */
function analysisContent(text, callback){
	var lineArray = text2LineArray(text);
	var newLineArray = modifyLineArray(lineArray);
	lineArray2HtmlContent(newLineArray, callback);
}
/**
* @param {String} text
* @param {Function} callback(err, htmlQuestions)
*/
function analysisQuestions(text, callback){
	var lineArray = text2LineArray(text);
	var newLineArray = modifyLineArray(lineArray);
	lineArray2QuestionArray(newLineArray, function(err, questionArray){
		if(err){
			callback(err, null);
			return;
		}
		newLineArray = questionArray2LineArray(questionArray);
//			console.log(newLineArray.join('\n'));
		lineArray2HtmlContent(newLineArray, callback);
	});
}

function questionArray2LineArray(questionArray){
	var lineArray = [];
	questionArray.forEach(function(question){
		var lineText = question.number + '. '+question.content;
		lineArray.push(lineText);
		var optionItems = question.optionItems;
		if(!optionItems) return;
		optionItems.forEach(function(optionItem){
			lineText = optionItem.code + '. '+optionItem.content;
			lineArray.push(lineText);
		});
	});
	return lineArray;
}
/**
*
* @param {Array<String>} lineArray
* @param {Function} callback(err, questionArray)
* 		{Array<Question>} questionArray
*/
function lineArray2QuestionArray(lineArray, callback){
	var questionArray = [];
	var hasError = false;
	var errorMessage='';
	lineArray.forEach(function(lineText, i){
		// if(hasError) return;
		if(isQuestionLine(lineText)){
			var questionObj = getQuestionFromLineText(lineText);
			if(!questionObj){
				lineArray[i] = setInvalidHtml(lineText);
				hasError = true;
				errorMessage +='Error [解析问题行失败， 格式错误！]:<p class="text-danger">'+lineText+'</p>';
				return;
			}
			questionArray.push(questionObj);
		}else if(isQuestionOptionItemLine(lineText)){
			if(questionArray.length == 0){
//				console.log('[Error] questionArray.length == 0)');
				lineArray[i] = setInvalidHtml(lineText);
				hasError = true;
				errorMessage +='Error [未找到选项所属问题行！]:<p class="text-danger">'+lineText+'</p>';
				return;
			}
			var questionObj = questionArray[questionArray.length - 1];
			var optionItemArray = getOptionItemArrayFromLineText(lineText);
			if(!optionItemArray){
				lineArray[i] = setInvalidHtml(lineText);
				hasError = true;
				errorMessage +='Error [解析选项失败，格式错误！]:<p class="text-danger">'+lineText+'</p>';
				return;
			}
			questionObj.type = QuestionType.Choice;
			questionObj.optionItems = questionObj.optionItems.concat(optionItemArray);
		}else{ //line start character is invalid.
			lineArray[i] = setInvalidHtml(lineText);
			hasError = true;
			errorMessage +='Error [未能识别此行数据，格式错误！]:<p class="text-danger">'+lineText+'</p>';
			return;
		}
	});
	var err = errorMessage? new Error(errorMessage): null;
	callback(err, questionArray);
}

/**
* @param {String} lineText
* @return {Question} 
*			null, if invalid format
* 			object, if ok.
*/
function getQuestionFromLineText(lineText){
	var regexp_number_content = /^(\d+)\s?\.(.+)$/;
	var regexp_space = new RegExp('^.*?'+QUESTION_SRC_UNDERLINE 
			+ '{'+ QUESTION_SRC_UNDERLINE_MIN_LENGTH +',}.*$');
	var data = regexp_number_content.exec(lineText);
	if(!data || data.length != 3){
		console.log('[Error] lineText:'+lineText);
		console.log('[Error] data:'+data);
		return null;
	}
	var qNumber = data[1];
	var qContent = data[2].trim();

	if(!regexp_space.test(qContent)){
		qContent += QUESTION_SRC_UNDERLINE.repeat(QUESTION_DB_UNDERLINE_LENGTH);
	}
	var questionObj = new Question();
	questionObj.number = qNumber;
	questionObj.content = convertUnderline(qContent);
	
	return questionObj;
}

function convertUnderline(text){
	var regexp = new RegExp(QUESTION_SRC_UNDERLINE 
		+ '{'+ QUESTION_SRC_UNDERLINE_MIN_LENGTH +',}', 
		'g');
	var replacement = ' '
		+ QUESTION_DB_UNDERLINE.repeat(QUESTION_DB_UNDERLINE_LENGTH)
		+ ' ';
	return text.replace(regexp, replacement);
}

/**
* @param {String} lineText
* @return {QuestionOptionItem} 
*			null, if invalid format
* 			object, if ok.
*/
function getOptionItemArrayFromLineText(lineText){
	var regexp_1 = /^([a-zA-Z])\s?\.(.+)$/;
	var regexp_2 = /^([a-zA-Z])\s?\.(.+)([a-zA-Z])\s?\.(.+)$/;
	var optionItemArray = [];

	var data = regexp_2.exec(lineText);
	if(!!data && data.length == 5){
		var optionItemObj1 = new QuestionOptionItem();
		optionItemObj1.code = data[1].toUpperCase();
		optionItemObj1.content = data[2].trim();
		optionItemArray.push(optionItemObj1);

		var optionItemObj2 = new QuestionOptionItem();
		optionItemObj2.code = data[3].toUpperCase();
		optionItemObj2.content = data[4].trim();
		optionItemArray.push(optionItemObj2);

		return optionItemArray;
	}

	data = regexp_1.exec(lineText);
	if(!!data && data.length == 3){
		var optionItemObj1 = new QuestionOptionItem();
		optionItemObj1.code = data[1].toUpperCase();
		optionItemObj1.content = data[2].trim();
		optionItemArray.push(optionItemObj1);
		return optionItemArray;
	}

	console.log('[Error] lineText:'+lineText);
	console.log('[Error] data:'+data);
	return null;
}

function setInvalidHtml(lineText){
	var f_start = '<p class="text-danger">* ';
	var f_end = '</p>';
	return f_start + lineText + f_end;
}

function isQuestionLine(lineText){
	var regexp = /^\d+\s?\.(.+)$/;
	return regexp.test(lineText);
}

function isQuestionOptionItemLine(lineText){
	var regexp = /^[a-zA-Z]\s?\.(.+)$/;
	return regexp.test(lineText);
}

function text2LineArray(text){
	return text.split(/\r\n|\n/);
}

function modifyLineArray(lineArray){
	var newLineArray = [];
	lineArray.forEach(function(line){
		line = line.trim();	//trim line
		if('' == line){ 	//remove empty line
			return;
		}
		newLineArray.push(line);
	});
	return newLineArray;
}
/**
 * @param {Array<String>} newLineArray
 * @param {Function} callback(err, htmlContent)
 */
function lineArray2HtmlContent(newLineArray, callback){
	var p_start = '<p class="article_p">';
	var p_end = '</p>'
	var separator = p_end + '\n' + p_start;
	var htmlContent = p_start + newLineArray.join(separator) + p_end;
	callback(null, htmlContent);
}


//################### Test ##########################

//var contents = '   \t   Reading new peaks of popularity.\n'
//	+'Arthur von Wiesenberger, He says.    \r\n\n'
//	+'Regardless of how it\'s sold.\n'
//	+'';
//var questions= 
//'1. Generally, audiences have more in common with those         .\n'
//+'who succeed than failure \n'
//+'who are enjoying success after struggling for their goal\n'
//+'who struggle than those who succeed in life.\n'
//+'who are prominent as well as tenacious\n'
//+'2. In the third paragraph, "If your father-in-law drove you nuts during the holiday weekend," what does the phrase "drove you nuts" mean?\n'
//+'A. was pleased with you              B. made you angry    \n'
//+'C. gave you nuts to eat               D. scolded you harshly\n'
//+'8. An amused         in response to an idea expressed in a meeting can destroy an otherwise credible communicator.'
//+'';

//#############################################
// var afterContents = analysisContent(contents);
// console.log('########################################');
// console.log(contents);
// console.log('########################################');
// console.log(afterContents);

// var afterQuestions = analysisQuestions(questions);
// console.log('########################################');
// console.log(questions);
// console.log('########################################');
// console.log(afterQuestions);

//console.log('finished');


